package main

import (
	"encoding/json"
	"fmt"
)

type Order struct {
	ID         string
	Name       string
	Quantity   int
	TotalPrice float64
}

func test() {
	o := Order{
		ID:         "1234",
		Name:       "learn go",
		Quantity:   3,
		TotalPrice: 30,
	}

	fmt.Printf("%+v\n", o) // {ID:1234 Name:learn go Quantity:3 TotalPrice:30}
	fmt.Printf("%#v\n", o) // main.Order{ID:"1234", Name:"learn go", Quantity:3, TotalPrice:30}

	b, err := json.Marshal(o)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%s\n", b) // {"ID":"1234","Name":"learn go","Quantity":3,"TotalPrice":30} 网络传输一般要求小写，go语言才要求的大写
}

type Order2 struct {
	ID          string
	name        string
	Quantity    int
	total_price float64
}

func test2() {
	o := Order2{
		ID:          "1234",
		name:        "learn go",
		Quantity:    3,
		total_price: 30,
	}

	b, err := json.Marshal(o)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%s\n", b) // {"ID":"1234","Quantity":3} 小写字段对外不可见
}

type Order3 struct { // tag
	ID         string  `json:"id"`
	Name       string  `json:"name"`
	Quantity   int     `json:"quantity"`
	TotalPrice float64 `json:"total_price"`
}

func test3() {
	o := Order3{
		ID:         "1234",
		Name:       "learn go",
		Quantity:   3,
		TotalPrice: 30,
	}

	b, err := json.Marshal(o)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%s\n", b) // {"id":"1234","name":"learn go","quantity":3,"total_price":30}
}

type Order4 struct { // tag
	ID string `json:"id"`
	//Name       string  `json:"name"`
	Name       string  `json:"name,omitempty"` // omit：省略，empty：空
	Quantity   int     `json:"quantity"`
	TotalPrice float64 `json:"total_price"`
}

func test4() {
	o := Order4{
		ID:         "1234",
		Quantity:   3,
		TotalPrice: 30,
	}

	b, err := json.Marshal(o)
	if err != nil {
		panic(err)
	}

	//fmt.Printf("%s\n", b) // {"id":"1234","name":"","quantity":3,"total_price":30} name不赋值也会显示
	fmt.Printf("%s\n", b) // {"id":"1234","quantity":3,"total_price":30}
}

type OrderItem struct {
	ID    string  `json:"id"`
	Name  string  `json:"name"`
	Price float64 `json:"price"`
}

type Order5 struct {
	ID         string    `json:"id"`
	Item       OrderItem `json:"item"`
	Quantity   int       `json:"quantity"`
	TotalPrice float64   `json:"total_price"`
}

func test5() {
	o := Order5{
		ID: "1234",
		Item: OrderItem{
			ID:    "item_1",
			Name:  "learn go",
			Price: 15,
		},
		Quantity:   3,
		TotalPrice: 30,
	}

	b, err := json.Marshal(o)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%s\n", b) // {"id":"1234","item":{"id":"item_1","name":"learn go","price":15},"quantity":3,"total_price":30}
}

type Order6 struct {
	ID         string     `json:"id"`
	Item       *OrderItem `json:"item"`
	Quantity   int        `json:"quantity"`
	TotalPrice float64    `json:"total_price"`
}

func test6() {
	o := Order6{
		ID: "1234",
		Item: &OrderItem{
			ID:    "item_1",
			Name:  "learn go",
			Price: 15,
		},
		Quantity:   3,
		TotalPrice: 30,
	}

	b, err := json.Marshal(o) // 能识别指针成员
	if err != nil {
		panic(err)
	}

	fmt.Printf("%s\n", b) // {"id":"1234","item":{"id":"item_1","name":"learn go","price":15},"quantity":3,"total_price":30}
}

type Order7 struct {
	ID         string      `json:"id"`
	Items      []OrderItem `json:"items"`
	TotalPrice float64     `json:"total_price"`
}

func test7() {
	o := Order7{
		ID: "1234",
		Items: []OrderItem{
			{
				ID:    "item_1",
				Name:  "learn go",
				Price: 15,
			},
			{
				ID:    "item_2",
				Name:  "interview",
				Price: 10,
			},
		},
		TotalPrice: 20,
	}

	b, err := json.Marshal(o) // 能识别指针成员
	if err != nil {
		panic(err)
	}

	fmt.Printf("%s\n", b) // {"id":"1234","items":[{"id":"item_1","name":"learn go","price":15},{"id":"item_2","name":"interview","price":10}],"total_price":20}
}

type Order8 struct {
	ID         string       `json:"id"`
	Items      []*OrderItem `json:"items"` // 指针数组
	TotalPrice float64      `json:"total_price"`
}

func test8() {
	o := Order8{
		ID: "1234",
		Items: []*OrderItem{
			{
				ID:    "item_1",
				Name:  "learn go",
				Price: 15,
			},
			{
				ID:    "item_2",
				Name:  "interview",
				Price: 10,
			},
		},
		TotalPrice: 20,
	}

	b, err := json.Marshal(o) // 能识别指针成员
	if err != nil {
		panic(err)
	}

	fmt.Printf("%s\n", b) // {"id":"1234","items":[{"id":"item_1","name":"learn go","price":15},{"id":"item_2","name":"interview","price":10}],"total_price":20}
}

func unmarshal() {
	s := `{"id":"1234","items":[{"id":"item_1","name":"learn go","price":15},{"id":"item_2","name":"interview","price":10}],"total_price":20}`
	var o Order7
	err := json.Unmarshal([]byte(s), &o)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%+v\n", o)
}

func parseNLP() {
	res := `{
"data": [
    {
        "synonym":"",
        "weight":"0.6",
        "word": "真丝",
        "tag":"材质"
    },
    {
        "synonym":"",
        "weight":"0.8",
        "word": "韩都衣舍",
        "tag":"品牌"
    },
    {
        "synonym":"连身裙;联衣裙",
        "weight":"1.0",
        "word": "连衣裙",
        "tag":"品类"
    }
]
}`
	m := make(map[string]interface{}) // json可以用map[string]interface{}来存储，但取值很麻烦，需要判断类型
	err := json.Unmarshal([]byte(res), &m)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%+v\n", m)
	// Type assertion
	fmt.Printf("%+v\n", m["data"].([]interface{})[2].(map[string]interface{})["synonym"])
}

func parseNLP2() {
	res := `{
"data": [
    {
        "synonym":"",
        "weight":"0.6",
        "word": "真丝",
        "tag":"材质"
    },
    {
        "synonym":"",
        "weight":"0.8",
        "word": "韩都衣舍",
        "tag":"品牌"
    },
    {
        "synonym":"连身裙;联衣裙",
        "weight":"1.0",
        "word": "连衣裙",
        "tag":"品类"
    }
]
}`
	m := struct {
		Data []struct {
			Synonym string `json:"synonym"`
			Tag     string `json:"tag"`
		} `json:"data"`
	}{}
	err := json.Unmarshal([]byte(res), &m)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%+v\n", m.Data[2].Synonym)
}

func main() {
	//test()
	//test2()
	//test3()
	//test4()
	//test5()
	//test6()
	//test7()
	//test8()
	//unmarshal()
	//parseNLP()
	parseNLP2()
}
